package com.lxl.core;

import com.lxl.config.SystemConfig;
import com.lxl.message.JsonMsgProvider;
import com.lxl.message.MessageProvider;
import com.lxl.message.XmlMsgProvider;
import com.lxl.pojo.InterfaceMonitor;
import org.apache.commons.io.IOUtils;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class TaskDataMeta {
    private final static String TASK_TYPE_TRANS = "trans";
    private final static String TASK_TYPE_JOB = "job";
    private final static String URL_PARAM_TRANS = TASK_TYPE_TRANS;
    private final static String URL_PARAM_JOB = TASK_TYPE_JOB;
    private final static String URL_PARAM_RESPONSE_TYPE = "type";
    private final static String URL_PARAM_VARIABLE = "param";
    private final static String RESPONSE_TYPE_JSON = "json";
    private final static String RESPONSE_TYPE_XML = "xml";
    private final static String DEFAULT_RESPONSE_TYPE = RESPONSE_TYPE_JSON;
    private final static String ETL_RESULT_KEY_XML = "XML@RESULT.FUNSO";
    private final static String ETL_RESULT_KEY_JSON = "JSON@RESULT.FUNSO";
    private final static String POST_CONTENT2ETL_KEY = "POST@START.FUNSO";

    public boolean requestValidate;
    public String taskType;//trans or job
    public String taskLocalConfigFileName;
    public Map<String, String> etlInputVariables;
    public String taskLocalConfigFilePath;
    public String templatePath;
    public String webResponseType;//json or xml
    public String etlResultKey;
    public MessageProvider msgProvider;

    public InterfaceMonitor interfaceMonitor;

    public TaskDataMeta(ServletRequest request) {
        validateUrlAndInitTaskType(request);
        if (requestValidate) {
            initTaskFilePath(request);
            initeInterfaceMonitor(request);
            initWebAndEtlOutputFomatFromUrl(request);
            initEtlInputVariables(request);
        }
    }

    protected boolean verifyTaskEffectiveness() {
        return (!requestValidate || !new File(taskLocalConfigFilePath).exists());
    }

    private void validateUrlAndInitTaskType(ServletRequest request) {
        if (request.getParameter(URL_PARAM_TRANS) != null && !request.getParameter(URL_PARAM_TRANS).isEmpty()) {
            taskType = TASK_TYPE_TRANS;
            requestValidate = true;
        } else if (request.getParameter(URL_PARAM_JOB) != null && !request.getParameter(URL_PARAM_JOB).isEmpty()) {
            taskType = TASK_TYPE_JOB;
            requestValidate = true;
        }
    }

    private void initWebAndEtlOutputFomatFromUrl(ServletRequest request) {
        webResponseType = request.getParameter(URL_PARAM_RESPONSE_TYPE);
        if (webResponseType != null && webResponseType.equals(RESPONSE_TYPE_XML)) {
            etlResultKey = ETL_RESULT_KEY_XML;
            msgProvider = new XmlMsgProvider();
        } else {
            webResponseType = DEFAULT_RESPONSE_TYPE;
            etlResultKey = ETL_RESULT_KEY_JSON;
            msgProvider = new JsonMsgProvider();
        }
    }

    private void initEtlInputVariables(ServletRequest request) {
        try {
            //获得输入kettle层变量映射<K, V>
            etlInputVariables = new HashMap<>();
            //GET请求参数
            String urlParamStr = request.getParameter(URL_PARAM_VARIABLE);
            //POST请求参数
            String postInputContent = IOUtils.toString(request.getInputStream(), "utf-8");
            if (urlParamStr != null && !urlParamStr.isEmpty()) {
                urlParamStr = new String(urlParamStr.getBytes("iso8859-1"), "utf-8");
                interfaceMonitor.setInputParam(urlParamStr);
                String[] variableStrList = urlParamStr.split("-");
                for (String variableStr : variableStrList) {
                    String[] tempKV = variableStr.split(":");
                    etlInputVariables.put(tempKV[0], tempKV[1]);
                }
            }
            if (postInputContent != null && !postInputContent.isEmpty()) {
                interfaceMonitor.setInputParam(postInputContent);
                etlInputVariables.put(POST_CONTENT2ETL_KEY, postInputContent);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void initTaskFilePath(ServletRequest request) {
        taskLocalConfigFileName = request.getParameter(taskType);

        if (taskType.equals(TASK_TYPE_JOB)) {
            taskLocalConfigFilePath = SystemConfig.SERVER_JOB_PATH + taskLocalConfigFileName.replace(".", SystemConfig.FILE_SEPARATOR) + SystemConfig.SUFFIX_JOB;
            templatePath = SystemConfig.SERVER_JOB_PATH + taskLocalConfigFileName.replace(".", SystemConfig.FILE_SEPARATOR) + SystemConfig.SUFFIX_TEMPLATE;
        } else {
            if (!taskLocalConfigFileName.contains(".")) {
                //如果是默认路径，ktr取/trans/transname.ktr
                taskLocalConfigFilePath = SystemConfig.SERVER_TRANS_PATH + taskLocalConfigFileName + SystemConfig.SUFFIX_TRANS;
                templatePath = SystemConfig.SERVER_TRANS_PATH + taskLocalConfigFileName + SystemConfig.SUFFIX_TEMPLATE;
            } else {
                //如果包含.，则ktr为/job/project/transname.ktr
                taskLocalConfigFilePath = SystemConfig.SERVER_JOB_PATH + taskLocalConfigFileName.replace(".", SystemConfig.FILE_SEPARATOR) + SystemConfig.SUFFIX_TRANS;
                templatePath = SystemConfig.SERVER_JOB_PATH + taskLocalConfigFileName.replace(".", SystemConfig.FILE_SEPARATOR) + SystemConfig.SUFFIX_TEMPLATE;
            }
        }
    }

    private void initeInterfaceMonitor(ServletRequest request) {
        interfaceMonitor = new InterfaceMonitor();
        interfaceMonitor.setInterfaceCategory(upperFirstCase(taskType));
        interfaceMonitor.setInterfaceName(taskLocalConfigFileName);
        interfaceMonitor.setVisitIP(getIpAddress((HttpServletRequest) request));
        interfaceMonitor.setVisitTime(new Date(System.currentTimeMillis()));
        //GET请求参数
        /*String urlParamStr = request.getParameter(URL_PARAM_VARIABLE);
        if (urlParamStr!=null && !urlParamStr.isEmpty()){
            interfaceMonitor.setInputParam(urlParamStr);
        }*/
        //POST请求参数
        /*String postInputContent = null;
        try {
            postInputContent = IOUtils.toString(request.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (postInputContent!=null && !postInputContent.isEmpty()){
            interfaceMonitor.setInputParam(postInputContent);
        }*/
    }

    private final static String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } else if (ip.length() > 15) {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = (String) ips[index];
                if (!("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }
        return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
    }

    private final static String upperFirstCase(String str) {
        char[] ch = str.toCharArray();
        if (ch[0] >= 'a' && ch[0] <= 'z') {
            ch[0] = (char) (ch[0] - 32);
        }
        return new String(ch);
    }
}
